#ifndef MOTOR_H
#define MOTOR_H
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <thread>
#include <QString>
#include <atomic>
#include <QByteArray>
#include <QObject>
#include <QMutex>
#include <QThread>
#include "decodeMotor.h"
#include <boost/system/error_code.hpp>
#include <boost/asio/serial_port.hpp>
#include <boost/asio.hpp>
#include <boost/timer.hpp>
#include "boost/circular_buffer.hpp"
#include "boost/signals2.hpp"
#include "src/base/Fast/config.h"


using namespace std;


#define PRINTCORRECT 1      // 打印链接时候的信息

typedef boost::circular_buffer<unsigned char> CCircularBuffer;


class Motor
{
public:

    ~Motor();
    static Motor* GetInstance(){
        static QMutex mutex;
        static QScopedPointer<Motor> inst;
        if (Q_UNLIKELY(!inst)) {
            mutex.lock();
            if (!inst) {
                inst.reset(new Motor);
            }
            mutex.unlock();
        }
        return inst.data();
    }
public:
    void sendCMDs(std::vector<uchar> &cmds);    // 基本处理函数
    void sendCMDs(std::vector<u16> &cmds);    // 基本处理函数
    void sendCMDs(std::vector<ulong> &cmds);
    void sendCMDs(u16 *cmds);
    void reconnectDevice();             //re连接串口
    void disconnectDevice();            //断开设备
    bool isDeviceOpend();               //设备是否正常


private:
    void recvReply( const boost::system::error_code &ec, size_t ) ;         // 设备应答
    void waitReply() ;                      // 等待设备应答
    void getDesc();                         // 获取描述信息
    void preConnectDevice();                //连接串口前的准备工做

    /// 线程同步锁
    std::recursive_mutex _mtx ;
    /// 条件变量
    std::condition_variable _condReply ;
    /// 条件变量锁
    std::mutex _mtxReply ;
    /// 是否已经应答
    std::atomic<bool> _bReply = ATOMIC_FLAG_INIT;
    /// asio 服务管理
    boost::asio::io_service _service ;
    /// 激光控制通信管理
    std::shared_ptr<boost::asio::serial_port> _serialPort_ptr ;

    std::thread _thService ;


public:
    std::vector<uchar> recivers;                                // 存放应答指令集合
    void setBuffSize(int );                                     // 设置循环缓冲区的大小
    void connectDevice(std::string,uint);                       // 连接串口

    // 循环发送区满，触发该信号
    boost::signals2::signal<void (std::vector<uchar>)> bufFull;





public:

    /**
     * @brief read_from_serial
     * @details 主动读取一帧数据从串口
     * @return
     */
    QByteArray read_from_serial();

private:
    /// 存放应答指令缓存
    unsigned char _oneBuffer[1] ;

    CCircularBuffer myBuffer;   // 循环缓冲区，检测到循环缓冲区满则发生信号

    std::string port_name ;
    uint port_bau ;


private:
    Motor();

};


#endif // MOTOR_H
